function [ kmlfilename ] = generateKML( Results, fileStr, parentpath )
%% Generates a KML file from the given Results struct.

%% Write/OPEN to kml file(s)
lookLat = 40.00305556;
lookLon = -105.264275;
lookAt = geopoint(lookLat, lookLon);
lookAt.Range = 1408;
lookAt.Heading = 351;
lookAt.Tilt = 59;
kmlfilename = [parentpath fileStr(1:end-4) '.kml'];
fid = fopen(kmlfilename,'w');
%% print header
fprintf(fid, '%s\n%s\n%s\n\t%s\n','<?xml version="1.0" encoding="UTF-8"?>','<kml xmlns="http://www.opengis.net/kml/2.2">','<Document>',['<name>' fileStr '</name>']);

%% print styles
% set table style for extended data
% 'Time of Data Point: min','Height error:  m','Clock Error: m','#SVs: ', ' HDOP: '
balloonStyle = sprintf('\t%s\n\t\t%s\n\t\t\t%s\n\t\t\t%s\n\t\t\t%s\n\t\t\t%s\n\t\t\t%s\n\t\t\t%s\n\t\t\t%s\n\t\t\t%s\n\t\t%s\n\t%s' ...
,      '<BalloonStyle>' ...
,        '<text>' ...
,          '<![CDATA[' ...
,          'This is $[name]<br/>' ...
,          '$[time/displayName] $[time]<br/>' ...
,          '$[heightError/displayName] $[heightError]<br/>' ...
,          '$[clockError/displayName] $[clockError]<br/>' ...
,          '$[SVs/displayName] $[SVs]' ...
,          '$[HDOP/displayName] $[HDOP]' ...
,          '$[magV/displayName] $[magV]' ...
,            ']]>' ...
,        '</text>' ...
,      '</BalloonStyle>');
fprintf(fid, '%s\n%s\n%s\n' ...
, '<Style id="balloonStyle">' ...  
, balloonStyle ...
, '</Style>');
% http://maps.google.com/mapfiles/kml/pal2/icon18.png
fprintf(fid, '%s\n\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t%s\n%s\n%s\n', '<Style id="P1">' ...
,'<IconStyle>' ...
,'<color>ff0000ff</color>' ...
, '<scale>0.3</scale>' ...
, '<Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>' ...
, '</IconStyle>' ...
, '</Style>');
fprintf(fid, '%s\n\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t%s\n%s\n%s\n', '<Style id="P2">' ...
,'<IconStyle>' ...
,'<color>ff1010ff</color>' ...
, '<scale>0.3</scale>' ...
, '<Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>' ...
, '</IconStyle>' ...
, '</Style>');
fprintf(fid, '%s\n\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t%s\n%s\n%s\n', '<Style id="P3">' ...
,'<IconStyle>' ...
,'<color>ff2020ff</color>' ...
, '<scale>0.3</scale>' ...
, '<Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>' ...
, '</IconStyle>' ...
, '</Style>');
fprintf(fid, '%s\n\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t%s\n%s\n%s\n', '<Style id="P4">' ...
,'<IconStyle>' ...
,'<color>ff3030ff</color>' ...
, '<scale>0.3</scale>' ...
, '<Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>' ...
, '</IconStyle>' ...
, '</Style>');
fprintf(fid, '%s\n\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t%s\n%s\n%s\n', '<Style id="P5">' ...
,'<IconStyle>' ...
,'<color>ff4040ff</color>' ...
, '<scale>0.3</scale>' ...
, '<Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>' ...
, '</IconStyle>' ...
, '</Style>');
fprintf(fid, '%s\n\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t%s\n%s\n%s\n', '<Style id="P6">' ...
,'<IconStyle>' ...
,'<color>ff5050ff</color>' ...
, '<scale>0.3</scale>' ...
, '<Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>' ...
, '</IconStyle>' ...
, '</Style>');
fprintf(fid, '%s\n\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t%s\n%s\n%s\n', '<Style id="P7">' ...
,'<IconStyle>' ...
,'<color>ff6060ff</color>' ...
, '<scale>0.3</scale>' ...
, '<Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>' ...
, '</IconStyle>' ...
, '</Style>');
fprintf(fid, '%s\n\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t%s\n%s\n%s\n', '<Style id="P8">' ...
,'<IconStyle>' ...
,'<color>ff7070ff</color>' ...
, '<scale>0.3</scale>' ...
, '<Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>' ...
, '</IconStyle>' ...
, '</Style>');
fprintf(fid, '%s\n\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t%s\n%s\n%s\n', '<Style id="P9">' ...
,'<IconStyle>' ...
,'<color>ff8080ff</color>' ...
, '<scale>0.3</scale>' ...
, '<Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>' ...
, '</IconStyle>' ...
, '</Style>');
fprintf(fid, '%s\n\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t%s\n%s\n%s\n', '<Style id="P10">' ...
,'<IconStyle>' ...
,'<color>ff9090ff</color>' ...
, '<scale>0.3</scale>' ...
, '<Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>' ...
, '</IconStyle>' ...
, '</Style>');
fprintf(fid, '%s\n\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t%s\n%s\n%s\n', '<Style id="P11">' ...
,'<IconStyle>' ...
,'<color>ffa0a0ff</color>' ...
, '<scale>0.3</scale>' ...
, '<Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>' ...
, '</IconStyle>' ...
, '</Style>');
fprintf(fid, '%s\n\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t%s\n%s\n%s\n', '<Style id="P12">' ...
,'<IconStyle>' ...
,'<color>ffb0b0ff</color>' ...
, '<scale>0.3</scale>' ...
, '<Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>' ...
, '</IconStyle>' ...
, '</Style>');
fprintf(fid, '%s\n\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t%s\n%s\n%s\n', '<Style id="P13">' ...
,'<IconStyle>' ...
,'<color>ffc0c0ff</color>' ...
, '<scale>0.3</scale>' ...
, '<Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>' ...
, '</IconStyle>' ...
, '</Style>');
fprintf(fid, '%s\n\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t%s\n%s\n%s\n', '<Style id="P14">' ...
,'<IconStyle>' ...
,'<color>ffd0d0ff</color>' ...
, '<scale>0.3</scale>' ...
, '<Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>' ...
, '</IconStyle>' ...
, '</Style>');
fprintf(fid, '%s\n\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t%s\n%s\n%s\n', '<Style id="P15">' ...
,'<IconStyle>' ...
,'<color>ffe0e0ff</color>' ...
, '<scale>0.3</scale>' ...
, '<Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>' ...
, '</IconStyle>' ...
, '</Style>');
fprintf(fid, '%s\n\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t%s\n%s\n%s\n', '<Style id="P16">' ...
,'<IconStyle>' ...
,'<color>ffffffff</color>' ...
, '<scale>0.3</scale>' ...
, '<Icon><href>http://maps.google.com/mapfiles/kml/pal2/icon18.png</href></Icon>' ...
, '</IconStyle>' ...
, '</Style>');
%% print position
dataIndex = find(Results.validPos == 1);
Vel = sqrt(Results.Vx.^2 + Results.Vy.^2 + Results.Vz.^2);
velocityBins = linspace(0, 2*mean(Vel),16);


for i = 1:length(dataIndex)
    % -----------set coordinates----------------
    llh = xyz2llh([Results.X(dataIndex(i)), Results.Y(dataIndex(i)), Results.Z(dataIndex(i))]);
    llh = llh*180/pi;
    % -----------set timestamp----------------
    YMDS = gps2ymds( Results.Time(dataIndex(i)), Results.week(dataIndex(i)));
    hours = floor(YMDS(4)/3600);
    min = floor(mod(YMDS(4)/3600, 1)*60);
    seconds = floor(YMDS(4) - hours*3600 - min*60);
    hoursStr = sprintf('%02d',hours);
    minStr = sprintf('%02d',min);
    secondsStr = sprintf('%02d',seconds);
    % -----------set velocity (icon)----------------
    velIndex = find( velocityBins >= Vel(dataIndex(i)), 1 );
    if isempty(velIndex)
        velIndex = 16;
    end
    % -----------set extended data----------------
    dataTime = sprintf('%s\n\t%s\n\t\t%s\n\t%s\n\t%s\n%s' ...
,        '<Data name="time">' ...
,          '<displayName><![CDATA[' ...
,            '<b>Time [min] </b>' ... 
,          ']]></displayName>' ...
,          ['<value>' num2str((Results.timeHours(dataIndex(i)) - Results.timeHours(dataIndex(1)))*60)  '</value>'] ... 
,        '</Data>');
    dataheightError = sprintf('%s\n\t%s\n\t\t%s\n\t%s\n\t%s\n%s' ...
,        '<Data name="heightError">' ...
,          '<displayName><![CDATA[' ...
,            '<b>Height Error </b>' ...
,          ']]></displayName>' ...
,          ['<value>' num2str(Results.pos_enu(dataIndex(i),5)) '</value>'] ...
,        '</Data>');
    dataclockError = sprintf('%s\n\t%s\n\t\t%s\n\t%s\n\t%s\n%s' ...
,        '<Data name="clockError">' ... 
,          '<displayName><![CDATA[' ...
,            '<b>Clock Error </b>' ...
,          ']]></displayName>' ...
,          ['<value>' num2str(Results.dt(dataIndex(i))) '</value>'] ...
,        '</Data>');
    dataSVs = sprintf('%s\n\t%s\n\t\t%s\n\t%s\n\t%s\n%s' ...
,        '<Data name="SVs">' ...
,          '<displayName><![CDATA[' ...
,            '<b>Num SVs </b>' ... 
,          ']]></displayName>' ...
,          ['<value>' num2str(Results.numSat(dataIndex(i)))  '</value>'] ... 
,        '</Data>');
    dataHDOP = sprintf('%s\n\t%s\n\t\t%s\n\t%s\n\t%s\n%s' ...
,        '<Data name="SVs">' ...
,          '<displayName><![CDATA[' ...
,            '<b>HDOP </b>' ... 
,          ']]></displayName>' ...
,          ['<value>' num2str(Results.HDOP(dataIndex(i)))  '</value>'] ... 
,        '</Data>');
    datamagV = sprintf('%s\n\t%s\n\t\t%s\n\t%s\n\t%s\n%s' ...
,        '<Data name="SVs">' ...
,          '<displayName><![CDATA[' ...
,            '<b>mag Vel [m/s] </b>' ... 
,          ']]></displayName>' ...
,          ['<value>' num2str(sqrt(Results.Vx(dataIndex(i))^2 + Results.Vy(dataIndex(i))^2 + Results.Vz(dataIndex(i))^2))  '</value>'] ... 
,        '</Data>');
    extendedData = sprintf('\t%s\n\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\t%s\n' ...
,      '<styleUrl>#balloonStyle</styleUrl>' ...
,      '<ExtendedData>' ...
,        dataTime ...
,        dataheightError ...
,        dataclockError ...
,        dataSVs ...
,        dataHDOP ...
,        datamagV ...
,      '</ExtendedData>');
    
    
    % ------------print point data to file
    fprintf(fid,'%s\n\t%s\n\t\t%s\n\t%s\n\t%s\n%s\n\t%s\n\t\t%s\n\t%s\n%s\n', ...
    '<Placemark>', ...
      '<TimeStamp>', ...
        ['<when>', num2str(YMDS(1)), '-', num2str(YMDS(2)),'-',num2str(YMDS(3)), 'T', hoursStr, ':', minStr, ':', secondsStr, 'Z</when>'], ...
      '</TimeStamp>', ...
      extendedData, ...
      ['<styleUrl>#P', num2str(velIndex), '</styleUrl>'], ...
      '<Point>', ...
        ['<coordinates>' num2str(llh(2)) ',' num2str(llh(1)) ',' num2str(llh(3)) '</coordinates>'], ...
      '</Point>', ...
    '</Placemark>');
   
end

%% print EOF
fprintf(fid, '\t%s\n%s', '</Document>','</kml>');







if ispc
        % On Windows(R) platforms display the KML file with:
        winopen(kmlfilename);
    elseif ismac
        % On Mac platforms display the KML file with:
        cmd = 'open -a Google\ Earth ';
        system([cmd kmlfilename]);
    else
        % On Linux platforms display the KML file with:
        cmd = 'googleearth ';
        system([cmd kmlfilename]);
end

end

